package br.com.velp.sudecap.daoimpl;

import br.com.velp.sudecap.comum.SpringConstants;
import br.com.velp.sudecap.dao.DocumentoDAO;
import br.com.velp.sudecap.dto.DocumentoParametrosConsultaDTO;
import br.com.velp.sudecap.entidade.Documento;
import br.com.velp.sudecap.util.DateUtils;
import br.com.velp.sudecap.util.NormalizacaoUtil;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Repository;

/**
 * <sumario>
 * <objetivo> "Rastreabilidade" </objetivo>
 * <autor> EDUARDO SANTOS DE OLIVEIRA </autor>
 * <versao> 1.0.0.0 </versao>
 * <data_criacao> 17.12.2013 </data_criacao>
 * <data_ultima_alteracao> N/A </data_ultima_alteracao>
 * <requisitos_afetados> RF002.01 - LISTAR DOCUMENTOS | RF002.02 - MANTER DOCUMENTOS </requisitos_afetados>
 * <descricao> Implementação da Interface Responsável Pelas 
 *             Operações de CRUD Referentes ao Contexto de 
 *             Documentos 
 * </descricao>
 * </sumario>
 */
@Repository("documentoDAO")
@Lazy(SpringConstants.LAZY_BEANS)
public class DocumentoDAOImpl implements DocumentoDAO {
    
    @Autowired
    private SessionFactory sessionFactory;

    @Override
    public Long salvar(Documento value) {
        
        Long id = (Long) getSession().save(value);
        getSession().flush();
        
        return id;
        
    }

    @Override
    public void atualizar(Documento value) {
        
        getSession().update(value);
        getSession().flush();
        
    }

    @Override
    public Documento obterPorId(Long id) {
        
        return (Documento) getSession().get(Documento.class, id);
        
    }

    @Override
    public void excluir(Documento value) {
        
        getSession().delete(value);
        getSession().flush();
        
    }
    
    @Override
    public int contarDocumentos(DocumentoParametrosConsultaDTO parametros) {
        
        Criteria criteria = getSession().createCriteria(Documento.class);
        criteria.setProjection(Projections.rowCount());
        
        adicionarParametrosConsulta(criteria, parametros);
        
        return ((Long) criteria.uniqueResult()).intValue();
        
    }

    @Override
    public List<Documento> buscarDocumentosPaginados(int firstResult, int maxResults, DocumentoParametrosConsultaDTO parametros, Order order) {
        
        Criteria criteria = getSession().createCriteria(Documento.class);
        
        adicionarParametrosConsulta(criteria, parametros);
        
        if (firstResult > 0) {
            criteria.setFirstResult(firstResult);
        }
        
        if (maxResults > 0) {
            criteria.setMaxResults(maxResults);
        }
        
        if (order != null) {
            criteria.addOrder(order);
        } else {
            criteria.addOrder(Order.asc("titulo"));
        }
        
        return criteria.list();
        
    }
    
    private void adicionarParametrosConsulta(Criteria criteria, DocumentoParametrosConsultaDTO parametros) {
        
        NormalizacaoUtil.normalizarEntidade(parametros);
        
        if (StringUtils.isNotBlank(parametros.getAssunto())) {
            criteria.add(Restrictions.ilike("", parametros.getAssunto(), MatchMode.ANYWHERE));
        }
        
        if (StringUtils.isNotBlank(parametros.getCodigo())) {
            criteria.add(Restrictions.ilike("", parametros.getCodigo(), MatchMode.ANYWHERE));
        }
        
        if (StringUtils.isNotBlank(parametros.getEmpreendimento())) {
            criteria.add(Restrictions.ilike("", parametros.getEmpreendimento(), MatchMode.ANYWHERE));
        }
        
        if (StringUtils.isNotBlank(parametros.getFormato())) {
            criteria.add(Restrictions.ilike("", parametros.getFormato(), MatchMode.ANYWHERE));
        }
        
        if (StringUtils.isNotBlank(parametros.getLocal())) {
            criteria.add(Restrictions.ilike("", parametros.getLocal(), MatchMode.ANYWHERE));
        }
        
        if (StringUtils.isNotBlank(parametros.getNumeroSudecap())) {
            criteria.add(Restrictions.ilike("", parametros.getNumeroSudecap(), MatchMode.ANYWHERE));
        }
        
        if (StringUtils.isNotBlank(parametros.getPalavras())) {
            criteria.add(Restrictions.ilike("", parametros.getPalavras(), MatchMode.ANYWHERE));
        }
        
        if (StringUtils.isNotBlank(parametros.getSituacao())) {
            criteria.add(Restrictions.eq("", parametros.getSituacao()));
        }
        
        if (StringUtils.isNotBlank(parametros.getTipo())) {
            criteria.add(Restrictions.eq("", parametros.getTipo()));
        }
        
        if (StringUtils.isNotBlank(parametros.getTitulo())) {
            criteria.add(Restrictions.ilike("", parametros.getTitulo(), MatchMode.ANYWHERE));
        }
        
        if (parametros.getDataInicio() != null) {
            criteria.add(Restrictions.ge("", DateUtils.zerarHoraMinutoSegundo(parametros.getDataInicio())));
        }
        
        if (parametros.getDataFim() != null) {
            criteria.add(Restrictions.le("", DateUtils.corrigirDataHoraFinal(parametros.getDataFim())));
        }
        
    }
    
    public Session getSession() {
        return this.sessionFactory.getCurrentSession();
    }

}
